package com.hopedove.workshop.viewmodel

import androidx.databinding.ObservableField
import androidx.databinding.ObservableInt
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.viewModelScope
import com.hadilq.liveevent.LiveEvent
import com.hopedove.data.Datetime
import com.hopedove.net.ApiCallResult
import com.hopedove.repository.CommonRepository
import com.hopedove.viewmodel.BaseViewModel
import com.hopedove.workshop.api.*
import com.hopedove.workshop.data.pojo.ObservableRunningSituation
import com.hopedove.workshop.repository.WorkshopUserRepository
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch

/**
 *  运转情况查询 ViewModel
 */
class WorkshopRunningSituationQueryViewModel(
    private val api: WorkshopApi,
    private val commonRepo: CommonRepository,
    private val userRepo: WorkshopUserRepository
) : BaseViewModel() {

    private var startDate = commonRepo.getServerDateTime().dateFormatEn()
    val displayStartDate = ObservableField("日期: $startDate")

    private var endDate = commonRepo.getServerDateTime().dateFormatEn()
    val displayEndDate = ObservableField("日期: $endDate")

    val displayName = ObservableField("")
    val fromMachineNo = ObservableField("")
    val toMachineNo = ObservableField("")

    private val _pickStartDate = LiveEvent<Datetime>()
    val pickStartDate: LiveData<Datetime> = _pickStartDate

    private val _pickEndDate = LiveEvent<Datetime>()
    val pickEndDate: LiveData<Datetime> = _pickEndDate

    private val _types = MutableLiveData<List<RunningSituationType>>()
    val types: LiveData<List<String>> = Transformations.map(_types) { list ->
        list.map { it.name }
    }
    val selectedTypeIndex = ObservableInt(-1)

    private val _workshops = MutableLiveData<List<WorkShopItem>>()
    val workshops: LiveData<List<String>> = Transformations.map(_workshops) { list ->
        list.map { it.name }
    }
    val selectedWorkshopIndex = ObservableInt(-1)

    // 计划类型
    private val _planTypes = MutableLiveData<List<RunningSituationType>>()
    val planTypes: LiveData<List<String>> = Transformations.map(_planTypes) { list ->
        list.map { it.name }
    }
    val selectedPlanTypeIndex = ObservableInt(-1)


    private var saveJob: Job? = null
    private var deleteJob: Job? = null
    private var queryJob: Job? = null

    // 运转情况列表
    private val _situations = LiveEvent<List<RunnningSituation>>()
    val observableSituations: LiveData<List<ObservableRunningSituation>> =
        Transformations.map(_situations) { list ->
            val types = _planTypes.value!!
            list.map {

                val planTypes = types.map { it.name }
                var planTypeIndex = types.map { it.code }.indexOf(it.planTypeCode)
                planTypeIndex = if (planTypeIndex < 0) 0 else planTypeIndex

                ObservableRunningSituation(
                    it.id,
                    it.type,
                    it.machineNo,
                    ObservableField(it.remark),
                    ObservableField(it.reason),
                    ObservableField(it.duration),
                    processInfo = it.processInfo,
                    creator = it.creator ?: "",
                    currentLoginCreator = userRepo.getSignedUserSession()?.userId ?: "",
                    planTypes = planTypes,
                    planTypeSelection = ObservableInt(planTypeIndex)
                )
            }
        }

    override fun load() = viewModelScope.launch {
        userRepo.getSignedInUserName()?.let { displayName.set("记录人：$it") }

        getTypes()
        getWorkshops()
        getPlanTypes()
        queryList()
    }


    // 点击选择日期控件
    fun onPickStartDateClicked() {
        val curDate = startDate
        _pickStartDate.value = Datetime.parseEnFormat(curDate)
    }

    // 结束日期选择
    fun onPickEndDateClicked() {
        val curDate = endDate
        _pickEndDate.value = Datetime.parseEnFormat(curDate)
    }


    // 更新日期
    fun updateStartDate(datetime: Datetime) {
        startDate = datetime.dateFormatEn()
        displayStartDate.set("日期: $startDate")
    }

    // 更新结束日期
    fun updateEndDate(datetime: Datetime) {
        endDate = datetime.dateFormatEn()
        displayEndDate.set("日期: $endDate")
    }

    fun onQueryClick() {
        queryList()
    }


    fun onDeleteClick() {
        deleteList()
    }

    fun onSaveClick() {
        saveList()
    }

    private fun saveList() {
        if (checkListForOperation().not()) return
        if (saveJob?.isCompleted?.not() == true) return

        val situations = observableSituations.value ?: return

        val observableChecked = mutableListOf<ObservableRunningSituation>()

        situations.zip(_situations.value!!) { observableItem, item ->
            if (observableItem.checked.get()) {
                observableChecked.add(observableItem)
            }
        }

        if (observableChecked.isEmpty()) return
        val userSession = userRepo.getSignedUserSession() ?: return

        saveJob = viewModelScope.launch {
            _loading.value = true

            val savingList = observableChecked.map {
                val planTypeCode =
                    _planTypes.value!!.first { plan -> plan.name == it.selectedPlanType }.code

                RunningSituationSave(
                    it.id,
                    it.remark.get() ?: "",
                    it.reason.get() ?: "",
                    it.duration.get() ?: "",
                    planTypeCode
                )
            }


            when (val result =
                api.runningSituationSave(userSession.userId, userSession.userName, savingList)) {

                is ApiCallResult.Success -> {
                    _toastText.value = "保存成功"
                    // 清除选择项
                    observableSituations.value?.forEach { it.checked.set(false) }
                }
                is ApiCallResult.Error -> {
                    _toastText.value = result.error
                }
            }

            _loading.value = false
        }


    }

    private fun deleteList() {
        if (checkListForOperation().not()) return

        if (deleteJob != null) return

        observableSituations.value?.also { list ->

            val remaining = mutableListOf<RunnningSituation>()
            val deleting = mutableListOf<RunnningSituation>()
            list.zip(_situations.value!!) { observableItem, item ->
                if (observableItem.checked.get()) {
                    deleting.add(item)
                } else {
                    remaining.add(item)
                }
            }

            if (deleting.isEmpty()) return@also

            deleteJob = viewModelScope.launch {
                _loading.value = true

                val deletingIds = deleting.joinToString(separator = ",") { it.id }
                when (val result = api.runningSituationDelete(deletingIds)) {
                    is ApiCallResult.Success -> {
                        _toastText.value = "删除成功"
                        _situations.value = remaining
                    }
                    is ApiCallResult.Error -> {
                        _toastText.value = result.message
                    }
                }

            }.apply {
                invokeOnCompletion {
                    deleteJob = null
                    _loading.value = false
                }
            }

        }
    }

    private fun checkListForOperation(): Boolean {
        if (observableSituations.value == null) {
            _toastText.value = "列表为空"
            return false
        }

        if (observableSituations.value!!.none { it.checked.get() }) {
            _toastText.value = "没有选择的条目"
            return false
        }
        return true
    }

    private fun getTypes() = viewModelScope.launch {
        when (val result = api.runningSituationGetTypes()) {
            is ApiCallResult.Success -> {
                val list = mutableListOf<RunningSituationType>()
                list.add(RunningSituationType("-1", "--请选择--"))
                list.addAll(result.data!!)
                _types.value = list
            }

            is ApiCallResult.Error -> {
                _toastText.value = result.error
            }
        }
    }

    private fun getWorkshops() = viewModelScope.launch {
        when (val result = api.getWorkshopItems()) {
            is ApiCallResult.Success -> {
                val list = mutableListOf<WorkShopItem>()
                list.add(WorkShopItem("-1", "--请选择--"))
                list.addAll(result.data!!)
                _workshops.value = list
            }
            is ApiCallResult.Error -> {
                _toastText.value = result.error
            }
        }
    }

    private suspend fun getPlanTypes() {

        when (val result = api.getPlanTypeList()) {
            is ApiCallResult.Success -> {
                val list = mutableListOf<RunningSituationType>()
                list.add(RunningSituationType("", "--请选择--"))
                list.addAll(result.data!!)
                _planTypes.value = list
            }

            is ApiCallResult.Error -> {
                _toastText.value = "计划类型列表获取失败"
            }
        }

    }

    private fun queryList() {
        if (queryJob?.isCompleted?.not() == true) return

        queryJob = viewModelScope.launch {
            _loading.value = true
            // 这里还是要判断【计划类型】是否为空，因为需要给列表条目装填计划类型数据
            if (_planTypes.value == null) {
                getPlanTypes()
            }

            if (_planTypes.value == null) {
                _loading.value = false
                _toastText.value = "计划类型列表为空"
                return@launch
            }

            val typeCode = if (types.value == null || selectedTypeIndex.get() <= 0) {
                ""
            } else {
                _types.value!![selectedTypeIndex.get()].code
            }

            val workshopId = if (workshops.value == null || selectedWorkshopIndex.get() <= 0) {
                ""
            } else {
                _workshops.value!![selectedWorkshopIndex.get()].id
            }

            val planTypeCode = if (planTypes.value == null || selectedPlanTypeIndex.get() <= 0) {
                ""
            } else {
                _planTypes.value!![selectedPlanTypeIndex.get()].code
            }

            val userSession = userRepo.getSignedUserSession()
            if (userSession != null) {
                val startDateEn = Datetime.parseEnFormat(startDate).dateFormatEn()
                val endDateEn = Datetime.parseEnFormat(endDate).dateFormatEn()

                val result = api.runningSituationQueryList(
                    startDateEn,
                    endDateEn,
                    fromMachineNo.get() ?: "",
                    toMachineNo.get() ?: "",
                    workshopId,
                    typeCode,
                    planTypeCode
                )

                when (result) {
                    is ApiCallResult.Success -> {
                        _situations.value = result.data!!
                    }

                    is ApiCallResult.Error -> {
                        _toastText.value = result.error
                    }
                }

            } else {
                // 未登录 ？
            }

            _loading.value = false
        }

    }

}